package ppu

import "github.com/imacks/bitflags-go"

const (
	MaskGrayscale                 = 0b00000001
	MaskLeftMost8PixelsBackground = 0b00000010
	MaskLeftMost8PixelsSprite     = 0b00000100
	MaskShowBackground            = 0b00001000
	MaskShowSprites               = 0b00010000
	MaskEmphasiseRed              = 0b00100000
	MaskEmphasiseGreen            = 0b01000000
	MaskEmphasiseBlue             = 0b10000000
)

const (
	EmphasiseRed   = uint8(0)
	EmphasiseGreen = uint8(1)
	EmphasiseBlue  = uint8(2)
)

type MaskRegister struct {
	Bits byte
}

// NewMaskRegister returns a new MaskRegister instance
func NewMaskRegister() *MaskRegister {
	return &MaskRegister{
		Bits: 0,
	}
}

// IsGrayscale returns true if the grayscale bit is set
func (m *MaskRegister) IsGrayscale() bool {
	return bitflags.Has(m.Bits, MaskGrayscale)
}

// LeftMost8PixelsBackground returns true if the leftmost 8 pixels of the background are shown
func (m *MaskRegister) LeftMost8PixelsBackground() bool {
	return bitflags.Has(m.Bits, MaskLeftMost8PixelsBackground)
}

// LeftMost8PixelsSprite returns true if the leftmost 8 pixels of the sprites are shown
func (m *MaskRegister) LeftMost8PixelsSprite() bool {
	return bitflags.Has(m.Bits, MaskLeftMost8PixelsSprite)
}

// ShowBackground returns true if the background is shown
func (m *MaskRegister) ShowBackground() bool {
	return bitflags.Has(m.Bits, MaskShowBackground)
}

// ShowSprites returns true if the sprites are shown
func (m *MaskRegister) ShowSprites() bool {
	return bitflags.Has(m.Bits, MaskShowSprites)
}

// Emphasise returns a list of colours to emphasise
func (m *MaskRegister) Emphasise() []uint8 {
	var result []uint8

	if bitflags.Has(m.Bits, MaskEmphasiseRed) {
		result = append(result, EmphasiseRed)
	}
	if bitflags.Has(m.Bits, MaskEmphasiseBlue) {
		result = append(result, EmphasiseBlue)
	}
	if bitflags.Has(m.Bits, MaskEmphasiseGreen) {
		result = append(result, EmphasiseGreen)
	}

	return result
}

// Update updates the mask register with the given data
func (m *MaskRegister) Update(data byte) {
	m.Bits = data
}
